package com.lingjtx.common.other.helper;

import com.lingjtx.common.core.RedisOptions;
import com.lingjtx.common.core.constant.Const;
import com.lingjtx.common.core.constant.RedisConfig;
import com.lingjtx.common.core.handle.ObjectPool;
import com.lingjtx.common.core.util.CommonUtil;
import com.lingjtx.common.core.util.StringUtil;
import com.lingjtx.common.other.http.Call;
import com.lingjtx.common.other.http.Callback;
import com.lingjtx.common.other.http.Network;
import com.lingjtx.common.other.http.RemoteService;
import com.lingjtx.common.other.model.weixin.OauthResponse;
import com.lingjtx.common.other.model.weixin.UserInfoRequest;
import com.lingjtx.common.other.model.weixin.UserInfoResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.http.HttpClient;
import java.util.UUID;

public enum WeiXinOauth {

    INSTANCE;

    public static final Logger log = LoggerFactory.getLogger(WeiXinOauth.class);

    public OauthResponse getOauthAccessToken(String code, String state, RedisOptions redisOptions, ObjectPool<HttpClient> objectPool) {
        return DataCachePool.INSTANCE.getWXOauthAccessToken(code, state, redisOptions, objectPool);
    }

    public void saveUserInfo(String accessToken, String openid, RedisOptions redisOptions, ObjectPool<HttpClient> objectPool) {
        if (StringUtil.isNotEmpty(accessToken) && StringUtil.isNotEmpty(openid)) {
            RemoteService service = Network.remote(RemoteService.class, objectPool);
            Call<UserInfoResponse> call = service.getUserInfo(new UserInfoRequest(accessToken, openid));
            call.enqueue(new Callback<UserInfoResponse>() {
                @Override
                public void onResponse(UserInfoResponse rspModel) {
                    // 请求成功
                    if (rspModel != null && openid.equals(rspModel.getOpenid())) {
                        redisOptions.set(openid, rspModel, RedisConfig.TIMEOUT_5_MIN);
                    }
                }

                @Override
                public void onFailure(String error) {
                    log.error("============微信拉起用户信息失败：{}", error);
                }
            });
        }
    }

    public String getBaseWeixinOauthUrl(RedisOptions redisOptions) {
        return getWeixinOauthUrl("snsapi_base", redisOptions);
    }

    public String getUserinfoWeixinOauthUrl(RedisOptions redisOptions) {
        return getWeixinOauthUrl("snsapi_userinfo", redisOptions);
    }

    public String getWeixinOauthUrl(String scope, RedisOptions redisOptions) {
        return getWeixinOauthUrl(scope, Const.WEBURL + "/login", redisOptions);
    }

    public String getBaseWeixinOauthUrl(String url, RedisOptions redisOptions) {
        return getWeixinOauthUrl("snsapi_base", url, redisOptions);
    }

    public String getUserinfoWeixinOauthUrl(String url, RedisOptions redisOptions) {
        return getWeixinOauthUrl("snsapi_userinfo", url, redisOptions);
    }

    public String getWeixinOauthUrl(String scope, String url, RedisOptions redisOptions) {
        String key = UUID.randomUUID().toString();
        redisOptions.set(key, "WeiXinOauth state check,create state in my server", RedisConfig.TIMEOUT_1_MIN);
        return getWeixinOauthUrl(scope, key, url);
    }

    private String getWeixinOauthUrl(String scope, String state, String url) {
        return "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                + Const.WEIXIN_APPID +
                "&redirect_uri="
                + CommonUtil.specialUrlEncode(url) +
                "&response_type=code&scope=" + scope + "&state="
                + state +
                "#wechat_redirect";
    }
}
